package org.grottarossa.tms.ui.console.psapv;




import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.ResourceBundle;

import org.grottarossa.template.data.enums.EnumWorkItemType;
import org.grottarossa.template.data.pojo.Menu.MenuType;
import org.grottarossa.template.data.pojo.workflows.Activity;
import org.grottarossa.template.data.pojo.workflows.WorkItem;
import org.grottarossa.template.data.pojo.workflows.Workflow;
import org.grottarossa.template.drivers.DriverException;
import org.grottarossa.template.drivers.components.tokens.CaseManagementId;
import org.grottarossa.template.drivers.components.tokens.GenericId;
import org.grottarossa.tms.PSAPV.ui.home.HomePage;
import org.grottarossa.tms.PSAPV.ui.home.HomePageFactory;
import org.grottarossa.tms.ui.console.ConsolePresenter;
import org.grottarossa.ui.core.Dialog.MessageBox;
import org.grottarossa.ui.core.Dialog.MessageBox.ButtonType;
import org.grottarossa.ui.core.Dialog.MessageBox.Buttons;
import org.grottarossa.ui.core.Dialog.MessageBoxListener;
import org.grottarossa.ui.core.casemanagement.CaseManagementPanel;
import org.grottarossa.ui.core.casemanagement.bpm.BaseBPMPanel;
import org.grottarossa.ui.core.casemanagement.bpm.WorkflowStarter;
import org.grottarossa.ui.core.casemanagement.menu.MenuPanelFactory;
import org.grottarossa.ui.core.casemanagement.menu.MenuPanelFactory.MenuPanelType;
import org.grottarossa.ui.core.components.QueryForwardPanel;
import org.grottarossa.ui.core.components.TablePanel;
import org.grottarossa.ui.core.i18n.DM;
import org.grottarossa.ui.core.layout.EmptyPanel;
import org.grottarossa.ui.exception.InternalException;

import com.vaadin.data.Item;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.terminal.Sizeable;
import com.vaadin.ui.Component;

/***
 * Gestisce la logica della console di PSAPV
 * @author 
 *
 */
public class PSAConsolePresenter extends ConsolePresenter<PSAConsoleView> implements ItemClickListener
{
	private static final long serialVersionUID = 2187258777022056661L;
	protected ResourceBundle m_localizer = DM.instance().getBundle(PSAConsolePresenter.class.getPackage().getName() + ".psapvCommonMessages");

	/***
	 * Gestisce i click sugli elementi del menu
	 * @author 
	 *
	 */
	private class RecordListener implements ItemClickListener
	{
		private static final long serialVersionUID = 1L;
		private Hashtable<String, String[]> m_defaultLayouts = new Hashtable<String, String[]>();
		private Hashtable<String, Hashtable<String, String>> m_defaultLayoutsCaptions = new Hashtable<String, Hashtable<String, String>>();
		private Hashtable<String, ArrayList<String>> m_showButtonsBarForLayouts = new Hashtable<String, ArrayList<String>>();
		private PSAConsoleView view;
		private final ResourceBundle m_localizer;

		private RecordListener (PSAConsoleView view, ResourceBundle localizer)
		{
			this.view = view;
			this.m_localizer = localizer;

			initDefaultLayouts();
		}

		private void initDefaultLayouts()
		{
			m_defaultLayouts.put("PSA Richiesta", new String[]{"ReviewProjectProcedure", "Scadenze"});

			Hashtable<String, String> richiestaCaptions = new Hashtable<String, String>();
			richiestaCaptions.put("ReviewProjectProcedure", m_localizer.getString("psa.defaultlayouts.caption.richiesta.detail"));
			richiestaCaptions.put("Scadenze", m_localizer.getString("psa.defaultlayouts.caption.richiesta.expiredates"));

			m_defaultLayoutsCaptions.put("PSA Richiesta", richiestaCaptions);

			ArrayList<String> showButtonsBarForLayouts = new ArrayList<String>();
			showButtonsBarForLayouts.add("Scadenze");
			m_showButtonsBarForLayouts.put("PSA Richiesta", showButtonsBarForLayouts);
		}

		public void itemClick(ItemClickEvent event)
		{
			try
			{
				//Query on Process
				if  ( (event.getItem().getItemProperty("WORKFLOWID") != null ) &&
						(event.getItem().getItemProperty("WORKFLOWID").getValue() != null ) )
				{
					Integer workflowId = (Integer)event.getItem().getItemProperty("WORKFLOWID").getValue();
					Integer workflowVersion = (Integer)event.getItem().getItemProperty("WORKFLOWVERSION").getValue();
					String stepName = (String)event.getItem().getItemProperty("WFWORKSTEPNAME").getValue();
					BigDecimal envelopeId = (BigDecimal)event.getItem().getItemProperty("WFROUTINGTICKETID").getValue();

					Workflow workflow;
					Activity activity = null;

					workflow = getWorkflow(workflowId, workflowVersion);
					activity = m_appSession.getBuilder().getWorkflowManagement().getActivity(workflow, stepName);

					WorkItem workItem = new WorkItem();
					workItem.setActivityName(activity.getActivityName());
					workItem.setObjectId( new GenericId(envelopeId));
					workItem.setWorkflowId(workflowId);
					workItem.setWorkflowVersion(workflowVersion);
					workItem.setWorkItemType(EnumWorkItemType.Process);
					workItem = m_appSession.getBuilder().getWorkflowManagement().getWorkItem(workflow, activity, workItem);

					BaseBPMPanel bpmPanel = new BaseBPMPanel(m_appSession, workItem, activity, workflow);
					bpmPanel.setHeight("100%");
					bpmPanel.setWidth("100%");

					EnumWorkItemType workItemType = workItem.getWorkItemType();

					if (workItemType.isCaseFolder())
						view.showInDetailArea(bpmPanel);
					else
					{
						view.showInPopup(bpmPanel);
					}
				}
				else if ( (event.getItem().getItemProperty("CASEFOLDERID") != null ) &&
						  (event.getItem().getItemProperty("CASEFOLDERID").getValue() != null ) )
				{
					BigDecimal idCF = (BigDecimal)event.getItem().getItemProperty("CASEFOLDERID").getValue();

					String layoutType = m_appSession.getBuilder().getRecordManagement().getCaseObjectLayout(new CaseManagementId(idCF));

					if(layoutType != null)
						layoutType = layoutType.split("\\.")[0];

					String [] layouts = new String[] {};
					Hashtable<String, String> layoutsCaptions = new Hashtable<String, String>();
					ArrayList<String> showButtonsBarForLayout = new ArrayList<String>();

					if(m_defaultLayouts.containsKey(layoutType))
						layouts = m_defaultLayouts.get(layoutType);

					if(m_defaultLayoutsCaptions.containsKey(layoutType))
						layoutsCaptions = m_defaultLayoutsCaptions.get(layoutType);

					if(m_showButtonsBarForLayouts.containsKey(layoutType))
						showButtonsBarForLayout = m_showButtonsBarForLayouts.get(layoutType);

					CaseManagementPanel cmPanel =
						new CaseManagementPanel(m_appSession, new CaseManagementId(idCF), layouts, layoutsCaptions,
								showButtonsBarForLayout, view);

					cmPanel.setSizeFull();

					view.showInDetailArea(cmPanel);
				}
				else if ((event.getItem().getItemProperty("S_ROWID") != null ) &&
						 (event.getItem().getItemProperty("S_ROWID").getValue() != null ) )
				{
					//TODO: Pezzotto Pesante. E' necessario un meccanismo per recuperare il templateID o il
					//templatenema
					BigDecimal idRow = (BigDecimal)event.getItem().getItemProperty("S_ROWID").getValue();
					//BigDecimal idTemplate = (BigDecimal)event.getItem().getItemProperty("TEMPLATEID").getValue();
					String sLayout = "PSA_FormazioneUtente";

					Component component = (Component) m_appSession.getLayoutFactory().createLayout(
							sLayout,new Class[] { BigDecimal.class},  new Object[] { idRow} );
					component.setSizeFull();

					view.showInPopup(component);
				}
				else if ((event.getItem().getItemProperty("DOCUMENTID") != null ) &&
						 (event.getItem().getItemProperty("DOCUMENTID").getValue() != null ) )
				{
					EmptyPanel panel = new EmptyPanel("Show document", "");
					panel.setSizeFull();

					view.showInPopup(panel);
				}
			}
			catch(Exception ex)
			{
				view.showError(ex);
			}
		}
	}


	public PSAConsolePresenter()
	{
		super();
	}

	@Override
	protected void customInitialize() throws DriverException
	{
		Component servicesMenuPanel = MenuPanelFactory.getMenuPanel(m_appSession, this.applicationName, MenuPanelType.Service, new ItemClickListener()
											{
												/**
												 *
												 */
												private static final long serialVersionUID = 1L;

												public void itemClick(ItemClickEvent event)
												{
													if (event.getItemId() == null)
														return;

												    showStartWorkflowQuestionPopup(event.getItem());
												}
											});

		Component processMenuPanel = MenuPanelFactory.getMenuPanel(m_appSession, this.applicationName, MenuPanelType.ProcessInstance, this);
		Component queriesMenuPanel = MenuPanelFactory.getMenuPanel(m_appSession, this.applicationName, MenuPanelType.Query, this);

		getView().setMenus(servicesMenuPanel, processMenuPanel, queriesMenuPanel);
		showHomePage();
	}

	/***
	 * Mostra nell'area di dettaglio della view la home page
	 */
	private void showHomePage()
	{
		try
		{
			HomePageFactory f = new HomePageFactory(m_appSession);
			HomePage home = f.createHomePage();
			home.setWidth(100, Sizeable.UNITS_PERCENTAGE);
			home.setHeight(100, Sizeable.UNITS_PERCENTAGE);
			getView().showInDetailArea(home);
		}
		catch(Exception ex)
		{
			getView().showError(ex);
		}
	}

	protected void showStartWorkflowQuestionPopup(Item item)
	{
		Integer m_currentWorkflowId = (Integer)item.getItemProperty("WorkflowId").getValue();
		Integer m_currentWorkflowVersion = (Integer)item.getItemProperty("WorkflowVersion").getValue();

		try {

			final Workflow wf = getWorkflow(m_currentWorkflowId, m_currentWorkflowVersion);
			if (wf == null)
				return;

			String caption = getCommonLocalizer()
					.getString("psa.popup.processo.caption");
			String message = getCommonLocalizer()
					.getString("psa.popup.processo.message");
			message = message.replace("{id}",
					String.format("%d", wf.getWorkflowId().getIdentity()));
			message = message.replace("{name}", wf.getWorkflowName());
			message = message.replace("{version}",
					String.format("%d", wf.getWorkflowVersion()));

//			MessageBox answerMessageBox = new MessageBox(caption, message,
//					new MessageBoxClickListener() {
//
//						public void buttonClick(ClickedButton button) {
//							if (button == ClickedButton.Ok)
//								startWorkflow(wf);
//						}
//					});

			new MessageBox(getView()
					.getApplication().getMainWindow(), caption, message,
					Buttons.YesNo, new MessageBoxListener() {
						public void manageButton(ButtonType buttonType,
								Object object) {
							if (buttonType == ButtonType.Yes
									|| buttonType == ButtonType.OK) {
								startWorkflow(wf);
							}
						}
					}, wf);
		}
		catch (DriverException e)
		{
			throw new InternalException(e);
		}
	}

	private Workflow getWorkflow(int workflowId, int workflowVersion) throws DriverException
	{
		//return new Workflow(new WorkFlowId(workflowId), workflowVersion);

		Workflow workflowToStart = null;

		for (Workflow wf: m_appSession.getBuilder().getWorkflowManagement().getWorkflows())
		{
			if (workflowId == (Integer)wf.getWorkflowId().getIdentity()
					&& (wf.getWorkflowVersion() == workflowVersion)
					)
				workflowToStart = wf;
		}
		return workflowToStart;
	}

	private void startWorkflow(Workflow workflow)
	{
		WorkflowStarter starter = new WorkflowStarter(m_appSession, getView(), null);

		if(starter.setWorkflow(workflow))
			starter.start(!starter.getWorkItemType().isCaseFolder());

	}

	public void itemClick(ItemClickEvent event) {

		if (event.getItemId() == null)
			return;

		String script = (String) event.getItem().getItemProperty("script").getValue();
		MenuType type = (MenuType) event.getItem().getItemProperty("type").getValue();

		if ( type == MenuType.Process ) {

			TablePanel tablePanel = new TablePanel(m_appSession, new RecordListener(getView(), m_localizer));
			tablePanel.draw(script, new HashMap<String, String>());
			tablePanel.setSizeFull();
			getView().showInDetailArea(tablePanel);


		} else if ( type == MenuType.Forward ) {

			String forward = (String) event.getItem().getItemProperty("forward").getValue();
			//retrieve forward
			String urlForward = m_localizer.getString(forward);

			QueryForwardPanel forwardPanel = new QueryForwardPanel(m_appSession);
			forwardPanel.draw(urlForward, script, new HashMap<String, String>());
			forwardPanel.setSizeFull();
			getView().showInDetailArea(forwardPanel);

		} else if ( type == MenuType.Graph ) {


		} else if ( type == MenuType.Query ) {


				TablePanel tablePanel = new TablePanel(m_appSession,  new RecordListener(getView(), m_localizer) );
				tablePanel.draw(script, new HashMap<String, String>());
				tablePanel.setSizeFull();
				getView().showInDetailArea(tablePanel);
		}
	}
}
